<template>
  <div v-loading="pageLoading" class="game_layout">
    <!-- 赛事编排 -->
    <div class="demo-input-suffix gl_searchBox">
      <el-row :gutter="20">
        <!-- 场地标名类型 -->
        <el-col :md="6" :lg="4">
          <p>赛事日期</p>
          <el-select v-model="currentGameDate" size="mini" filterable placeholder="请选择赛事日期" @change="onGameDateChange">
            <el-option v-for="(item, index) in gameDateList" :key="index" :value="item" :label="item" />
          </el-select>
        </el-col>
      </el-row>
    </div>

    <!-- 功能按钮区域 -->
    <el-row :gutter="20" class="gl_my_15">
      <!-- 平均分配编排 -->
      <el-col :span="24">
        <el-button type="primary" size="mini" @click="clickAvgArrange()">平均分配编排</el-button>
      </el-col>
    </el-row>

    <!-- 赛事编排列表 -->
    <div class="location_card_wrap">
      <el-card v-for="(item, index) in dataList" :key="index" shadow="hover" class="location_card" :class="item.isStretch ? 'location_card_long' : ''">
        <div slot="header" class="gl_clear">
          <div class="location_title gl_fl">{{ item.name }} 场地</div>
          <div class="gl_fl" style="line-height:40px;font-size:13px">
            <span v-show="item.len">
              （共{{ item.len }}场，淘汰赛{{ item.competitiveLen }}场，打分赛{{ item.noneCompetitiveLen }}场）
            </span>
          </div>
          <div class="gl_fr">
            <div v-show="item.isStretch" class="contrl_wrap gl_fl gl_mr_10">
              <el-button type="text" @click="clickGameArrange(item)">赛事编排</el-button>
              <el-button type="text" @click="clickSetCode(item)">编码设置</el-button>
              <el-button type="text" @click="clickCodeModify(item)">编码修改</el-button>
              <el-button type="text" @click="clickSelectTable(item)">勾选选择</el-button>
              <el-button type="text" @click="clickMigrateUnit(item)">转移</el-button>
              <el-button type="text" @click="clickClearArrange(item)">清空</el-button>
            </div>
            <div class="gl_fl">
              <i class="show_hide_btn" :class="item.isStretch ? 'el-icon-d-arrow-left' : 'el-icon-d-arrow-right'" @click="stretchArragePanel(item)" />
            </div>
          </div>
        </div>
        <div class="location_card_body">
          <el-collapse :value="0" accordion>
            <el-collapse-item v-for="(jtem, jndex) in item.children" :key="jndex" :title="formatSessionDateTitle(jtem)" :name="jndex">
              <div>
                <el-table v-show="!item.isStretch" height="280" :data="jtem.children" size="mini">
                  <el-table-column prop="code" label="编码" width="80" />
                  <el-table-column label="比赛名称">
                    <template slot-scope="scope">
                      <span class="gl_mr_5">{{ scope.row.categoryName }}</span>
                      <span class="gl_mr_5">{{ scope.row.eventGroupName }}</span>
                      <span class="gl_mr_5">{{ genderDictMap[scope.row.genderCode].value }}</span>
                      <span class="gl_mr_5">{{ scope.row.eventName }}</span>
                      <span v-if="scope.row.phaseName === '决赛' && scope.row.unitNum ===2 && scope.row.eventFormatCode === 'BronzeMedal'">{{ '铜牌赛' }}</span>
                      <span v-else>{{ scope.row.phaseName }}</span>
                      <span v-if="scope.row.phaseName === '决赛' && scope.row.unitNum ===2 && scope.row.eventFormatCode === 'BronzeMedal'" class="gl_mr_5">第{{ 1 }}场</span>
                      <span v-else>第{{ scope.row.unitNum }}场</span>
                    </template>
                  </el-table-column>
                </el-table>
                <el-table v-show="item.isStretch" :ref="'table_' + item.id + '_' + jtem.id" height="280" :data="jtem.children" size="mini" @selection-change="tableSelectionChange($event, jtem, item)">
                  <el-table-column type="selection" width="55" />
                  <el-table-column type="index" :index="jtem.index" label="序号" align="center" width="50" />
                  <el-table-column prop="code" label="编码" width="140" />
                  <el-table-column label="比赛名称">
                    <template slot-scope="scope">
                      <span class="gl_mr_5">{{ scope.row.categoryName }}</span>
                      <span class="gl_mr_5">{{ scope.row.eventGroupName }}</span>
                      <span class="gl_mr_5">{{ genderDictMap[scope.row.genderCode].value }}</span>
                      <span class="gl_mr_5">{{ scope.row.eventName }}</span>
                      <span v-if="scope.row.phaseName === '决赛' && scope.row.unitNum ===2 && scope.row.eventFormatCode === 'BronzeMedal'" class="gl_mr_5">{{ '铜牌赛' }}</span>
                      <span v-else class="gl_mr_5">{{ scope.row.phaseName }}</span>
                      <span v-if="scope.row.phaseName === '决赛' && scope.row.unitNum ===2 && scope.row.eventFormatCode === 'BronzeMedal'">第{{ 1 }}场</span>
                      <span v-else>第{{ scope.row.unitNum }}场</span>
                    </template>
                  </el-table-column>
                  <el-table-column label="参赛人员" width="74">
                    <template slot-scope="scope">
                      <el-button type="text" size="mini" @click="showGameMember(scope.row)">参赛人员</el-button>
                    </template>
                  </el-table-column>
                  <el-table-column label="操作" align="center" width="86">
                    <template slot-scope="scope">
                      <div class="gl_clear">
                        <el-button :disabled="scope.$index === 0" class="gl_fl" type="text" size="mini" @click="clickMoveUp(scope.row, scope.$index, jtem.children)">上移</el-button>
                        <el-button :disabled="scope.$index === jtem.children.length - 1" class="gl_fr" type="text" size="mini" @click="clickMoveDown(scope.row, scope.$index, jtem.children)">下移</el-button>
                      </div>
                    </template>
                  </el-table-column>
                </el-table>
              </div>
            </el-collapse-item>
          </el-collapse>
          <div v-if="!item.children.length" class="no_data_session">
            <span>暂无数据，请配置单元数据</span>
          </div>
        </div>
      </el-card>
    </div>

    <div v-if="!dataList.length && !pageLoading" class="gl_noData_mockTable">
      <p>暂无数据</p>
    </div>

    <set-code ref="modalSetCode" :title="modalSetCode.title" @onSubmitSetCode="submitSetCode" />
    <edit-code ref="modalEditCode" :prop-data="modalEditCode.propsData" @onSubmitEditCode="submitEditCode" />
    <migrate-unit ref="modalMigrateUnit" :title="modalMigrateUnit.title" :game-date-list="gameDateList" @onSubmitMigrateUnit="submitMigrateUnit" />
    <select-table ref="modalSelectTable" :title="modalSelectTable.title" :options="modalSelectTable.options" @onSubmitSelectTable="submitSelectTable" />
    <game-arrange
      ref="modalGameArrange"
      :title="modalGameArrange.title"
      :prop-data="{
        competitionId: competitionId,
        currentGameDate: currentGameDate, // 当前选中赛事日期
        arrangeList: unArrangeList, // 未编排的数据
        arrangeListAll: pageList, // 全部编排数据
        layOutType: modalGameArrange.layOutType, // 弹层类型，对应编排或平均编排
        gameDateList: gameDateList, // 比赛日期
        locationList: locationList, // 场地数据
        currentUnitBlock: modalGameArrange.currentUnitBlock, // 当前选中的场地编排(有数据结构)
        pageDataList: dataList // 所有的场地编排(有数据结构)
      }"
      @onSubmitNormalArrange="submitNormalArrangeForUnit"
      @onSubmitAverageArrange="submitAverageArrange"
    />
    <member-competitive ref="modalMemberCompetitive" :prop-data="modalMemberCompetitive.memberData" />
    <member-none-competitive ref="modalMemberNoneCompetitive" :prop-data="modalMemberNoneCompetitive.memberData" />
  </div>
</template>

<script>
import { CopyData, deepCopy } from '@/lib';
import { mapState, mapActions } from 'vuex';

import SetCode from './gameLayout/setCode.vue';
import EditCode from './gameLayout/editCode.vue';
import SelectTable from './gameLayout/selectTable.vue';
import MigrateUnit from './gameLayout/migrateUnit.vue';
import GameArrange from './gameLayout/gameArrange.vue';
import MemberCompetitive from './gameLayout/memberCompetitive.vue';
import MemberNoneCompetitive from './gameLayout/memberNoneCompetitive.vue';

import {
  api_GET_EventsManagementCompetitionDay, // 获取比赛日期
  api_GET_EventsManagementScheduleUnit, // 查询编排列表Unit级
  api_PUT_EventsManagementScheduleUnitUnitCode, // 修改Unit编码
  api_POST_EventsManagementScheduleUnitSetUnitCodes, // 更新Unit列表的编码
  api_PUT_EventsManagementScheduleUnitSessionByUnits, // 更新Unit列表的Session
  api_PUT_EventsManagementScheduleUnitClearSession, // 清空Unit的Session
  api_GET_EventsManagementCompetitionLocation, // 查询场地列表
  api_GET_EventsManagementCompetitionSession, // 查询单元列表
  api_PUT_EventsManagementScheduleUnitSessionByAverage, // 平均分配编排
  api_PUT_EventsManagementScheduleUnitSessionByPhases, // 更新Phase列表的Session
  api_PUT_EventsManagementScheduleUnitSessionByUnitsManual, // 更新编排手工
  api_GET_EventsManagementUnitResultCompetitiveByUnitIdUnitId, // 根据UnitId查询竞技类参赛人员
  api_GET_EventsManagementUnitResultNoneCompetitiveByUnitIdUnitId // 根据UnitId查询非竞技类参赛人员
} from '@/extend/api/gameswaggerApi/app';

import {
  Api_GET_EventsManagementCompetitionDayQO, // 获取比赛日期
  Api_GET_EventsManagementScheduleUnitQO, // 查询编排列表Unit级
  SiSTKWEventsManagementScheduleUnitCodeDto, // 修改Unit编码
  SiSTKWEventsManagementSetUnitCodesInput, // 更新Unit列表的编码
  SiSTKWEventsManagementUpdateSessionByUnitInput, // 更新Unit列表的Session
  SiSTKWEventsManagementClearSessionInput, // 清空Unit的Session
  Api_GET_EventsManagementCompetitionLocationQO, // 查询场地列表
  Api_GET_EventsManagementCompetitionSessionQO, // 查询单元列表
  SiSTKWEventsManagementUpdateSessionAverageInput, // 平均分配编排
  SiSTKWEventsManagementUpdateSessionByPhaseInput, // 更新Phase列表的Session
  SiSTKWEventsManagementUpdateSessionByUnitManualInput // 更新编排手工
} from '@/lib/form/game/swaggerForm';

export default {
  name: 'Logistic',
  components: {
    SelectTable,
    EditCode,
    SetCode,
    MigrateUnit,
    GameArrange,
    MemberCompetitive,
    MemberNoneCompetitive
  },
  data() {
    return {
      pageLoading: true,
      competitionId: '', // 赛事ID
      currentGameDate: '', // 当前选中的赛事日期
      gameDateList: [], // 赛事日期下拉列表
      gameDateQO: new Api_GET_EventsManagementCompetitionDayQO(),
      gameLocationQO: new Api_GET_EventsManagementCompetitionLocationQO(),
      gameSessionQO: new Api_GET_EventsManagementCompetitionSessionQO(),
      scheduleUnitQO: new Api_GET_EventsManagementScheduleUnitQO(),
      averageArrangeVO: new SiSTKWEventsManagementUpdateSessionAverageInput(),
      pageList: [], // getPageList 获取的数据
      locationList: [], // location 列表数据
      sessionList: [], // session 列表数据
      dataList: [], // 编排数据列表
      // 表格多选数据存储
      multipleSelection: {},
      // 编辑编码
      modalEditCode: {
        propsData: null, // 向子组件传递的数据
        vo: new SiSTKWEventsManagementScheduleUnitCodeDto()
      },
      // 编码设置
      modalSetCode: {
        title: '编码设置', // 模态框标题
        currentIds: [], // 选中的ID集合
        vo: new SiSTKWEventsManagementSetUnitCodesInput()
      },
      // 清除编排
      modalClearArrange: {
        title: '清除编排', // 模态框标题
        vo: new SiSTKWEventsManagementClearSessionInput()
      },
      // 转移
      modalMigrateUnit: {
        title: '转移', // 模态框标题
        currentIds: [],
        currentSessionId: '', // 转移时勾选数据的sessionID 如果有多个只需传一个
        vo: new SiSTKWEventsManagementUpdateSessionByUnitInput()
      },
      // 表格选择
      modalSelectTable: {
        currentLocationForSelection: '', // 当前选中的
        title: '',
        options: []
      },
      // 赛事编排
      modalGameArrange: {
        title: '赛事编排',
        layOutType: '', // ('average' | 'normal')编排类型，是平均编排还是普通编排，决定确认编排后弹出哪个窗口
        currentUnitBlock: null // 当前选择的单元块，有相关判断，不可使用空对象
      },
      modalMemberNoneCompetitive: {
        memberData: []
      },
      modalMemberCompetitive: {
        memberData: {}
      },
      // stretch 数据记录，防止刷新数据折叠收起来
      stretchData: {}
    };
  },
  computed: {
    ...mapState({
      dict: state => state.dict.dict
    }),
    // 处理 genderCode 字典为对象形式，方便取值。
    genderDictMap () {
      const _map = {};
      for (let i = 0; i < this.dict.gender.length; i++) {
        const item = this.dict.gender[i];
        _map[item.code] = item;
      }
      return _map;
    },
    // 未编排的数据
    unArrangeList() {
      return this.pageList.filter(item => !item.sessionId);
    }
  },
  created () {
    // 从路由中获取赛事ID
    this.getDict();
    this.getGameIdFromRoute();
    this.getGameDate();
  },
  methods: {
    ...mapActions({ getDict: 'dict/getDict' }),
    // 从路由中获取赛事ID
    getGameIdFromRoute () {
      const _id = this.$route.params.id;
      this.competitionId = _id;
      this.gameDateQO.competitionId = _id;
      this.gameLocationQO.competitionId = _id;
      this.gameSessionQO.CompetitionId = _id;
    },
    // 通过接口获取赛事比赛日期
    getGameDate () {
      this.pageLoading = true;
      api_GET_EventsManagementCompetitionDay(this.gameDateQO)
        .then(
          res => {
            this.pageLoading = false;
            this.gameDateList = res.items.map(item => item.date.slice(0, 10));
            this.currentGameDate = this.gameDateList[0];
            this.getGameLocation();
          }
        )
        .catch(
          error => {
            this.pageLoading = false;
            this.$message({
              message: `比赛日期获取失败！ ${error.error.message}`,
              type: 'error',
              showClose: true
            });
          }
        );
    },
    // 通过接口获取赛事场地
    getGameLocation () {
      this.pageLoading = true;
      api_GET_EventsManagementCompetitionLocation(this.gameLocationQO)
        .then(
          res => {
            this.pageLoading = false;
            this.locationList = res.items;
            this.getGameSession();
          }
        )
        .catch(
          error => {
            this.pageLoading = false;
            this.$message({
              message: `比赛场地获取失败！ ${error.error.message}`,
              type: 'error',
              showClose: true
            });
          }
        );
    },
    // 通过接口获取单元信息
    getGameSession () {
      this.gameSessionQO.Day = this.currentGameDate;
      delete this.gameSessionQO.LocationCode;
      delete this.gameSessionQO.SkipCount;
      delete this.gameSessionQO.MaxResultCount;
      this.pageLoading = true;
      api_GET_EventsManagementCompetitionSession(this.gameSessionQO)
        .then(
          res => {
            this.pageLoading = false;
            this.sessionList = res.items;
            this.getPageList();
          }
        )
        .catch(
          error => {
            this.pageLoading = false;
            this.$message({
              message: `比赛单元获取失败！ ${error.error.message}`,
              type: 'error',
              showClose: true
            });
          }
        );
    },
    // 获取页面展示数据
    getPageList () {
      this.pageLoading = true;
      this.scheduleUnitQO.CompetitionId = this.competitionId;
      // this.scheduleUnitQO.Date = this.currentGameDate;
      delete this.scheduleUnitQO.Date;
      delete this.scheduleUnitQO.LocationCode;
      delete this.scheduleUnitQO.SkipCount;
      delete this.scheduleUnitQO.Page;
      delete this.scheduleUnitQO.MaxResultCount;
      api_GET_EventsManagementScheduleUnit(this.scheduleUnitQO)
        .then(
          res => {
            this.pageLoading = false;
            this.pageList = res.items;
            this.formatPageListData(res.items);
            this.dataList = this.formatShowBaseList();
          }
        )
        .catch(
          error => {
            this.$message({
              message: `编排获取失败！ ${error.error.message}`,
              type: 'error',
              showClose: true
            });
          }
        );
    },
    // 处理页面展示的数据
    formatPageListData (list) {
      const _session = this.sessionList;
      const _sessionMap = {};
      _session.forEach(item => {
        _sessionMap[item.id] = item;
      });

      list.forEach(item => {
        if (item.sessionId && item.sessionId in _sessionMap) {
          if (_sessionMap[item.sessionId].children) {
            _sessionMap[item.sessionId].children.push(item);
          } else {
            _sessionMap[item.sessionId].children = [item];
          }
        }
      });
    },
    // 格式化出基本数据结构，便于页面渲染
    formatShowBaseList () {
      const _location = deepCopy(this.locationList);
      for (let i = 0; i < _location.length; i++) {
        const item = _location[i];
        const _locationCode = item.code;
        const _sessionList = this.formatSessionDataByLocationCode(_locationCode);
        this.countDataChidrenLen(_sessionList);
        item.children = _sessionList;

        if (item.id in this.stretchData) {
          item.isStretch = this.stretchData[item.id];
        } else {
          item.isStretch = false;
          this.stretchData[item.id] = item.isStretch;
        }

        item.len = 0;
        item.competitiveLen = 0;
        item.noneCompetitiveLen = 0;
        _sessionList.forEach(jtem => {
          item.len += jtem.len;
          item.competitiveLen += jtem.competitiveLen || 0;
          item.noneCompetitiveLen += jtem.noneCompetitiveLen || 0;
        });

        // 序号计算 start
        for (let j = 0; j < item.children.length; j++) {
          const jtem = item.children[j];
          if (j === 0) {
            jtem.index = j + 1;
            jtem.beginIndex = jtem.len; // 方便后面确认index
          } else {
            jtem.index = item.children[j - 1].beginIndex + 1;
            jtem.beginIndex = item.children[j - 1].beginIndex + jtem.len;
          }
        }
        // 序号计算 end
      }
      return _location;
    },
    // 根据Session 原数据格式化 Session数据
    formatSessionDataByLocationCode(code) {
      const _session = this.sessionList;
      const _listByCode = _session.filter(item => item.locationCode === code);

      _listByCode.forEach(item => {
        item.len = item.children ? item.children.length : 0;
        item.$title = this.formatSessionDate(item);
      });
      return _listByCode;
    },
    // 比赛日切换
    onGameDateChange (gameDate) {
      this.currentGameDate = gameDate;
      this.getGameLocation();
    },
    /* -- modal-line -- */
    // 上移预览内的编排
    clickMoveUp (item, index, list) {
      if (index === 0) return;
      // const _spliceItem = list.splice(index, 1);
      // list.splice(index - 1, 0, _spliceItem[0]);
      // moveArrangeVO: new SiSTKWEventsManagementUpdateSessionByUnitManualInput(),
      const _currentVO = new SiSTKWEventsManagementUpdateSessionByUnitManualInput();
      _currentVO.id = item.id;
      _currentVO.sessionId = item.sessionId;
      _currentVO.orderInSession = list[index - 1].orderInSession;
      const _preVO = new SiSTKWEventsManagementUpdateSessionByUnitManualInput();
      _preVO.id = list[index - 1].id;
      _preVO.sessionId = list[index - 1].sessionId;
      _preVO.orderInSession = item.orderInSession;

      this.submitMove([_currentVO, _preVO]);
    },
    // 下移预览内的编排
    clickMoveDown (item, index, list) {
      if (list.length - 1 === index) return;
      // const _spliceItem = list.splice(index, 1);
      // list.splice(index + 1, 0, _spliceItem[0]);
      const _currentVO = new SiSTKWEventsManagementUpdateSessionByUnitManualInput();
      _currentVO.id = item.id;
      _currentVO.sessionId = item.sessionId;
      _currentVO.orderInSession = list[index + 1].orderInSession;
      const _nextVO = new SiSTKWEventsManagementUpdateSessionByUnitManualInput();
      _nextVO.id = list[index + 1].id;
      _nextVO.sessionId = list[index + 1].sessionId;
      _nextVO.orderInSession = item.orderInSession;
      this.submitMove([_currentVO, _nextVO]);
    },
    // 移动编排API
    submitMove (list) {
      api_PUT_EventsManagementScheduleUnitSessionByUnitsManual(list)
        .then(
          res => {
            this.getGameLocation();
          }
        )
        .catch(
          error => {
            this.$message({
              message: `编排移动失败！ ${error.error.message}`,
              type: 'error',
              showClose: true
            });
          }
        );
    },
    /* -- modal-line -- */
    // 点击设置编码
    clickSetCode (data) {
      const _selectNum = this.countTableSelection(data.id);

      if (_selectNum !== 0) {
        // 勾选了数据的处理
        this.modalSetCode.currentIds = [];
        const _selectData = this.multipleSelection[data.id];
        const _sumSelectData = this.sumTableSelection(_selectData);
        this.modalSetCode.currentIds = _sumSelectData.map(item => item.id);
        this.$refs.modalSetCode.open();
      } else {
        // 未勾选数据，给出提示
        this.$message({
          message: `请勾选需要设置编码的比赛场次！`,
          type: 'warning',
          showClose: true
        });
      }
    },
    // 确认设置编码
    submitSetCode (data) {
      CopyData(data, this.modalSetCode.vo);
      this.modalSetCode.vo.ids = this.modalSetCode.currentIds;
      api_POST_EventsManagementScheduleUnitSetUnitCodes(this.modalSetCode.vo)
        .then(
          res => {
            this.getGameLocation();
            this.$refs.modalSetCode.changeSubmitLoading(false);
            this.$refs.modalSetCode.close();
            this.$message({
              message: `编码设置成功！`,
              type: 'success',
              showClose: true
            });
          }
        )
        .catch(
          error => {
            this.$refs.modalSetCode.changeSubmitLoading(false);
            this.$message({
              message: `编码设置错误！ ${error.error.message}`,
              type: 'error',
              showClose: true
            });
          }
        );
    },
    /* -- modal-line -- */
    // 点击编码修改
    clickCodeModify (item) {
      const canModify = this.canICodeModify(item);
      if (canModify) {
        const _currentData = this.multipleSelection[item.id];
        const _voData = this.fingDataToEditCode(_currentData);
        this.modalEditCode.propsData = _voData;
        this.$refs.modalEditCode.open();
      }
    },
    // 确认修改编码
    submitEditCode (data) {
      CopyData(data, this.modalEditCode.vo);
      this.modalEditCode.vo.id = data.id;
      api_PUT_EventsManagementScheduleUnitUnitCode(this.modalEditCode.vo)
        .then(
          res => {
            this.getGameLocation();
            this.$refs.modalEditCode.changeSubmitLoading(false);
            this.$refs.modalEditCode.close();
            this.$message({
              message: `编码修改成功！`,
              type: 'success',
              showClose: true
            });
          }
        )
        .catch(
          error => {
            this.$refs.modalEditCode.changeSubmitLoading(false);
            this.$message({
              message: `编码修改错误！ ${error.error.message}`,
              type: 'error',
              showClose: true
            });
          }
        );
    },
    // 是否可以修改编码
    canICodeModify (item) {
      const _key = item.id;
      const tableSelectionNum = this.countTableSelection(_key);
      if (tableSelectionNum === 0) {
        this.$message({
          message: `请勾选(单选) 场地${item.name} 需要修改编码的比赛场次！`,
          type: 'warning',
          showClose: true
        });
        return false;
      }

      if (tableSelectionNum > 1) {
        this.$message({
          message: `修改编码仅能选择一个比赛场次！`,
          type: 'warning',
          showClose: true
        });
        return false;
      }
      return true;
    },
    // 查找需要修改编码的数据
    fingDataToEditCode (data) {
      for (const k in data) {
        const ktem = data[k];
        if (ktem.length) {
          return ktem[0]; // 因每次修改编码仅能修改一个，所以数组中只会存在一个数据
        }
      }
      return null;
    },
    /* -- modal-line -- */
    // 点击勾选选择
    clickSelectTable (item) {
      this.modalSelectTable.currentLocationForSelection = item.id;
      const _options = this.makeSelectOptions(item);
      this.modalSelectTable.options = _options;
      this.modalSelectTable.title = item.name + '场地 勾选选择';
      this.$refs.modalSelectTable.open();
    },
    // 生成SelectTable所需的下拉选项
    makeSelectOptions (data) {
      const _list = data.children;
      const _options = [];
      for (let i = 0; i < _list.length; i++) {
        const item = _list[i];
        _options.push({
          sessionId: item.id,
          value: item.$title,
          label: item.$title
        });
      }
      return _options;
    },
    // 确认表格选择模态框
    submitSelectTable (data) {
      this.toggleSelectionTable(data);
    },
    // 勾选表格数据
    toggleSelectionTable(data) {
      let tableData = '';
      const refVmName = `table_${this.modalSelectTable.currentLocationForSelection}_${data.value}`;
      const refVm = this.$refs[refVmName][0];
      tableData = this.findDataByKey(this.dataList, 'id', this.modalSelectTable.currentLocationForSelection);
      tableData = this.findDataByKey(tableData, 'id', data.value);

      if (tableData) {
        const _list = tableData.children;
        if (_list && _list.length) {
          // 根据组件需求，需要循环调用方法
          refVm.clearSelection();
          if (data.startNum < tableData.index) {
            return;
          }
          const _sliceStartNum = data.startNum - tableData.index;
          const _sliceEndNum = data.endNum - tableData.index + 1;
          const _currentList = _list.slice(_sliceStartNum, _sliceEndNum);
          for (let i = 0; i < _currentList.length; i++) {
            const item = _currentList[i];
            refVm.toggleRowSelection(item);
          }
        }
      } else {
        console.log('toggleSelectionTable -> tableData 没有取到');
      }
    },
    /* -- modal-line -- */
    // 点击清除编排
    clickClearArrange (item) {
      const _selectNum = this.countTableSelection(item.id);

      if (_selectNum !== 0) {
        // 勾选了数据的处理
        const _selectData = this.multipleSelection[item.id];
        this.$confirm('您确定要清空选中的编排吗？', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
          .then(() => {
            this.pageLoading = true;
            const _sumSelectData = this.sumTableSelection(_selectData);
            // 清空时需要传递一个sessionId，多个sessionId时仅传一个，后端约定如此。
            this.modalClearArrange.vo.sessionId = _sumSelectData[0].sessionId;
            const _ids = _sumSelectData.map(item => item.id);
            this.submitClearArrange(_ids);
          });
      } else {
        // 未勾选数据，给出提示
        this.$message({
          message: `请勾选需要清空的比赛场次！`,
          type: 'warning',
          showClose: true
        });
      }
    },
    // 确认清除编排
    submitClearArrange (idList) {
      this.modalClearArrange.vo.ids = idList;
      api_PUT_EventsManagementScheduleUnitClearSession(this.modalClearArrange.vo)
        .then(
          res => {
            this.getGameLocation();
            this.pageLoading = false;
            this.$message({
              message: `清空编排成功！`,
              type: 'success',
              showClose: true
            });
          }
        )
        .catch(
          error => {
            this.pageLoading = false;
            this.$message({
              message: `清空编排错误！ ${error.error.message}`,
              type: 'error',
              showClose: true
            });
          }
        );
    },
    /* -- modal-line -- */
    // 点击转移单元
    clickMigrateUnit (data) {
      const _selectNum = this.countTableSelection(data.id);
      if (_selectNum !== 0) {
        const _selectData = this.multipleSelection[data.id];
        const _sumSelectData = this.sumTableSelection(_selectData);
        this.modalMigrateUnit.currentSessionId = _sumSelectData[0].sessionId;
        this.modalMigrateUnit.currentIds = _sumSelectData.map(item => item.id);
        this.$refs.modalMigrateUnit.open();
      } else {
        this.$message({
          message: `请勾选需要转移的比赛场次！`,
          type: 'warning',
          showClose: true
        });
      }
    },
    // 确认转移单元
    submitMigrateUnit (data) {
      if (data.positionType !== 'Custom') {
        delete this.modalMigrateUnit.vo.positionNum;
      } else {
        this.modalMigrateUnit.vo.positionNum = '';
      }
      this.modalMigrateUnit.vo.ids = this.modalMigrateUnit.currentIds;
      this.modalMigrateUnit.vo.sourceSessionId = this.modalMigrateUnit.currentSessionId;
      CopyData(data, this.modalMigrateUnit.vo);

      if (this.modalMigrateUnit.vo.positionNum) {
        const _num = this.findIndexInLocationSession(data);
        // 如果没有找到合适位置，则插入到最后
        if (!_num) {
          this.modalMigrateUnit.vo.positionType = 'Bottom';
          delete this.modalMigrateUnit.vo.positionNum;
        } else {
          // this.modalMigrateUnit.vo.positionNum = Number(this.modalMigrateUnit.vo.positionNum);
          this.modalMigrateUnit.vo.positionNum = Number(_num);
        }
      }
      api_PUT_EventsManagementScheduleUnitSessionByUnits(this.modalMigrateUnit.vo)
        .then(
          res => {
            this.$refs.modalMigrateUnit.changeSubmitLoading(false);
            this.$refs.modalMigrateUnit.close();
            this.getGameLocation();
            this.$message({
              message: `转移编排成功！`,
              type: 'success',
              showClose: true
            });
          }
        )
        .catch(
          error => {
            this.$refs.modalMigrateUnit.changeSubmitLoading(false);
            this.$message({
              message: `转移编排错误！ ${error.error.message}`,
              type: 'error',
              showClose: true
            });
          }
        );
    },
    // 从场地单元中找到与Index符合得数据
    findIndexInLocationSession (obj) {
      const _data = this.dataList;
      const _location = _data.find(item => item.code === obj.location);
      let _orderInSession;
      if (_location) {
        const _sessionList = _location.children || [];
        const _session = _sessionList.find(item => item.id === obj.destinationSessionId);
        const _index = _session.index;
        const _targetNum = Number(obj.positionNum);

        if (_session && _session.children) {
          // 如果小于目标值 那么插在最前面
          if (_targetNum <= _index && _session.children.length) {
            _orderInSession = _session.children[0].orderInSession;
          } else {
            for (let i = 0; i < _session.children.length; i++) {
              const item = _session.children[i];
              const _computeIndex = i + _index;
              if (_computeIndex === _targetNum) {
                _orderInSession = item.orderInSession;
                break;
              }
            }
          }
        } else {
          // 单元中没有数据，说明是空的单元，那么返回undefined 后面处理成插入底部
          return _orderInSession;
        }
      }
      return _orderInSession;
    },
    /* -- modal-line -- */
    // 点击赛事编排
    clickGameArrange (item) {
      this.modalGameArrange.layOutType = 'normal';
      this.modalGameArrange.currentUnitBlock = item;
      this.modalGameArrange.title = item.name ? `赛事编排 - ${item.name}场地` : '赛事编排';
      this.$refs.modalGameArrange.open();
    },
    // 确定 普通 赛事编排 Phase级别
    submitNormalArrangeForPhase (data) {
      const _vo = new SiSTKWEventsManagementUpdateSessionByPhaseInput();
      CopyData(data, _vo);
      api_PUT_EventsManagementScheduleUnitSessionByPhases(_vo)
        .then(
          res => {
            this.getGameLocation();
            this.$refs.modalGameArrange.changeNormalArrangeSubmitLoading(false);
            this.$refs.modalGameArrange.closeNormalArrangeModal();
            this.$refs.modalGameArrange.close();
            this.$message({
              message: `赛事编排成功`,
              type: 'success',
              showClose: true
            });
          }
        )
        .catch(
          error => {
            this.$message({
              message: `赛事编排失败，${error.error.message}`,
              type: 'error',
              showClose: true
            });
            this.$refs.modalGameArrange.changeNormalArrangeSubmitLoading(false);
          }
        );
    },
    // 确定 普通 赛事编排 Unit 级别
    submitNormalArrangeForUnit (data) {
      const _vo = new SiSTKWEventsManagementUpdateSessionByUnitInput();
      CopyData(data, _vo);
      api_PUT_EventsManagementScheduleUnitSessionByUnits(_vo)
        .then(
          res => {
            this.getGameLocation();
            this.$refs.modalGameArrange.changeNormalArrangeSubmitLoading(false);
            this.$refs.modalGameArrange.closeNormalArrangeModal();
            this.$refs.modalGameArrange.close();
            this.$message({
              message: `赛事编排成功`,
              type: 'success',
              showClose: true
            });
          }
        )
        .catch(
          error => {
            this.$message({
              message: `赛事编排失败，${error.error.message}`,
              type: 'error',
              showClose: true
            });
            this.$refs.modalGameArrange.changeNormalArrangeSubmitLoading(false);
          }
        );
    },
    /* -- modal-line -- */
    // 点击 平均 分配编排
    clickAvgArrange () {
      this.modalGameArrange.layOutType = 'average';
      this.modalGameArrange.currentUnitBlock = null;
      this.modalGameArrange.title = '平均赛事编排';
      this.$refs.modalGameArrange.open();
    },
    // 确定 平均 赛事编排
    submitAverageArrange (list, ids) {
      const _sessionIds = list.map(item => item.sessionId);
      this.averageArrangeVO.ids = ids;
      this.averageArrangeVO.sessionIds = _sessionIds;
      this.averageArrangeApi();
    },
    // 平均编排赛事API
    averageArrangeApi () {
      api_PUT_EventsManagementScheduleUnitSessionByAverage(this.averageArrangeVO)
        .then(
          res => {
            this.getGameLocation();
            this.$refs.modalGameArrange.changeAverageArrangeSubmitLoading(false);
            this.$refs.modalGameArrange.closeAverageArrangeModal();
            this.$refs.modalGameArrange.close();
            this.$message({
              message: `赛事编排成功`,
              type: 'success',
              showClose: true
            });
          }
        )
        .catch(
          error => {
            this.$refs.modalGameArrange.changeAverageArrangeSubmitLoading(false);
            this.$message({
              message: `赛事编排失败，${error.error.message}`,
              type: 'error',
              showClose: true
            });
          }
        );
    },
    /* -- modal-line -- */
    // 点击查看参赛人员
    showGameMember (row) {
      const _eventTypeCode = row.eventTypeCode;
      this.pageLoading = true;
      if (_eventTypeCode === 'Competitive') {
        this.getCompetitiveMember(row.id);
      }
      if (_eventTypeCode === 'NoneCompetitive') {
        this.getNoneCompetitiveMember(row.id);
      }
    },
    // 查看非竞技类参赛人员
    getNoneCompetitiveMember(id) {
      api_GET_EventsManagementUnitResultNoneCompetitiveByUnitIdUnitId(id)
        .then(
          res => {
            this.pageLoading = false;
            this.modalMemberNoneCompetitive.memberData = res;
            this.$refs.modalMemberNoneCompetitive.open();
          }
        )
        .catch(
          error => {
            this.$message({
              message: `人员获取失败，${error.error.message}`,
              type: 'error',
              showClose: true
            });
          }
        );
    },
    // 查看竞技类参赛人员
    getCompetitiveMember(id) {
      api_GET_EventsManagementUnitResultCompetitiveByUnitIdUnitId(id)
        .then(
          res => {
            this.pageLoading = false;
            this.modalMemberCompetitive.memberData = res;
            this.$refs.modalMemberCompetitive.open();
          }
        )
        .catch(
          error => {
            this.$message({
              message: `人员获取失败，${error.error.message}`,
              type: 'error',
              showClose: true
            });
          }
        );
    },
    // 伸展收缩编排面板
    stretchArragePanel (item) {
      const _stretch = !item.isStretch;
      item.isStretch = _stretch;
      this.stretchData[item.id] = item.isStretch;
    },
    /* -- 内部公共方法 -- */
    // 表格复选框勾选
    tableSelectionChange (val, valParent, valArea) {
      if (!this.multipleSelection[valArea.id]) {
        this.multipleSelection[valArea.id] = {};
      }
      this.multipleSelection[valArea.id][valParent.id] = val;
    },
    // 计算选择表格勾选的数量
    countTableSelection (idKey) {
      let selectNum = 0;
      const _data = this.multipleSelection[idKey];
      for (const k in _data) {
        const ktem = _data[k];
        selectNum = selectNum + ktem.length;
      }
      return selectNum;
    },
    // 根据ID查找数据
    findDataByKey(data, key, val) {
      if (Object.prototype.toString.call(data).slice(8, -1) === 'Object') {
        data = [data];
      }
      for (const k in data) {
        const ktem = data[k];
        if (ktem[key] && ktem[key] === val) {
          return ktem;
        }
        if (ktem.children && ktem.children.length) {
          const _result = this.findDataByKey(ktem.children, key, val);
          if (_result) {
            return _result;
          }
        }
      }
    },
    // 并集表格选中的数据
    sumTableSelection (selectData) {
      // 输入 => 输出
      // { 'morning': [{1},{2}], 'evening': [{3}] } => [{1}, {2}, {3}]
      let returnArr = [];
      for (const k in selectData) {
        const ktem = selectData[k];
        returnArr = returnArr.concat(ktem);
      }
      return returnArr;
    },
    // 计算子集数量
    countDataChidrenLen (data) {
      for (const k in data) {
        const ktem = data[k];
        if (ktem.children) {
          ktem.len = ktem.children.length;
          ktem.competitiveLen = this.computeCompetitiveNum(ktem.children);
          ktem.noneCompetitiveLen = this.computeNoneCompetitiveNum(ktem.children);
        }
      }
    },
    // 计算淘汰赛多少场次
    computeCompetitiveNum(data) {
      let num = 0;
      data.forEach(item => {
        if (item.eventTypeCode === 'Competitive') {
          num++;
        }
      });
      return num;
    },
    // 计算打分赛多少场次
    computeNoneCompetitiveNum(data) {
      let num = 0;
      data.forEach(item => {
        if (item.eventTypeCode === 'NoneCompetitive') {
          num++;
        }
      });
      return num;
    },
    // 格式化Session时间标题
    formatSessionDateTitle (data) {
      const _startTime = data.startTime.slice(11, 16);
      const _endTime = data.endTime.slice(11, 16);
      const _time = data.type + ' ' + _startTime + ' - ' + _endTime;
      let returnStr = `${_time}`;
      if (data.len) {
        returnStr += ` （共${data.len}场`;
        if (data.competitiveLen) {
          returnStr += `，淘汰赛${data.competitiveLen}场`;
        }
        if (data.noneCompetitiveLen) {
          returnStr += `，打分赛${data.noneCompetitiveLen}场`;
        }
        returnStr += `）`;
      }
      return returnStr;
      // return `${_time} （共${data.len}场，淘汰赛${data.competitiveLen || 0}场，打分赛${data.noneCompetitiveLen || 0}场）`;
    },
    // 格式化Session时间
    formatSessionDate (data) {
      const _startTime = data.startTime.slice(11, 16);
      const _endTime = data.endTime.slice(11, 16);
      const _time = data.type + ' ' + _startTime + ' - ' + _endTime;
      return _time;
    }
  }
};
</script>

<style>
.game_layout {
  position: relative;
}
.game_layout .el-card__body {
  padding: 0 20px;
}
.game_layout .el-table,
.game_layout .el-table__body-wrapper {
  min-height: auto;
}
.session_title {
  padding: 10px 0;
  font-size: 14px;
  line-height: 20px;
}
.location_card_wrap {
  white-space: nowrap;
  overflow-x: auto;
  padding-bottom: 10px;
}
.location_card {
  display: inline-block;
  width: 450px;
  height: 600px;
  margin-right: 20px;
  margin-bottom: 5px;
  vertical-align: top;
}
.location_card:last-child {
  margin-right: 0;
}
.game_layout .el-collapse {
  border: none;
}
.location_title {
  line-height:40px;
  font-weight:bold;
}
.no_data_session {
  padding-top: 120px;
  color: #909399;
  font-size: 14px;
  text-align: center;
}
.location_card_wrap .el-card__body {
  padding-right: 0;
  padding-left: 0;
}

.location_card_body {
  padding: 0 20px;
  height: 520px;
  overflow-y: auto;
}

.show_hide_btn {
  color: #1890FF;
  cursor: pointer;
  line-height: 40px;
}
.location_card_long {
  width: 920px;
}

</style>
